
/*
 * Visualizer.java
 *
 * Created on Jan 18, 2010, 9:17:57 PM
 */

package org.femto.compmod.gui;

import java.util.Map.Entry;
import org.femto.compmod.vis.VisualizerViewport;

import java.util.*;
import java.awt.BorderLayout;
import java.sql.SQLException;
import javax.media.opengl.*;
import javax.swing.JToolBar;
import javax.swing.JToggleButton;
import java.awt.event.*;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JRadioButton;
import org.femto.compmod.vis.Camera;
import org.femto.math.vis.*;

/**
 *
 * @author root
 */
public class Visualizer extends javax.swing.JInternalFrame
implements MouseListener, MouseMotionListener, MouseWheelListener {
    private GLCanvas canvas;
    private GLCapabilities caps;
    private JToolBar toolBar;
    private VisualizerViewport viewport;

    /** Creates new form Visualizer */
    public Visualizer() throws SQLException, IllegalArgumentException {
        init();
    }

    private void init() throws SQLException, IllegalArgumentException {

        viewport = new VisualizerViewport();

        GLCapabilities caps = new GLCapabilities();
        caps.setDoubleBuffered(true);
        caps.setAccumRedBits(16);
        caps.setAccumGreenBits(16);
        caps.setAccumBlueBits(16);
        caps.setAccumAlphaBits(16);
        
        canvas  = new GLCanvas(caps);
        canvas.addGLEventListener(viewport);
        canvas.addMouseListener(this);
        canvas.addMouseMotionListener(this);
        canvas.addMouseWheelListener(this);

        toolBar = new JToolBar();
        toolBar.setFloatable(false);
        addToolBarButtons();

        setClosable(true);
        setIconifiable(true);
        setMaximizable(true);
        setResizable(true);
        setTitle("Visualizer");
        setPreferredSize(new java.awt.Dimension(800, 600));

        add(canvas, BorderLayout.CENTER);
        add(toolBar, BorderLayout.PAGE_END);
        pack();
    }

    public void mouseMoved(MouseEvent e) {
      //System.out.println("Mouse moved " + e);
        //viewport.getManips().move(e.getX(), canvas.getHeight()-e.getY(), e.getModifiers());
        //canvas.swapBuffers();
        viewport.getCamera().move(e.getX(), canvas.getHeight()-e.getY(), e.getModifiers());
        canvas.repaint();
    }

    public void mouseDragged(MouseEvent e) {
      //  System.out.println("Mouse dragged " + e);
        viewport.getCamera().drag(e.getX(), canvas.getHeight()-e.getY(), e.getModifiers());
        
        //canvas.swapBuffers();
        canvas.repaint();
    }

    public void mousePressed(MouseEvent e) {
      // System.out.println("Mouse pressed " + e);
        viewport.getCamera().beginDrag(e.getX(), canvas.getHeight()-e.getY(), e.getModifiers());
        //canvas.swapBuffers();
        canvas.repaint();
    }

    public void mouseReleased(MouseEvent e) {
       //System.out.println("Mouse released (# of clicks: " + e.getClickCount() + ") " + e);
        viewport.getCamera().endDrag(e.getX(), canvas.getHeight()-e.getY(), e.getModifiers());
        //canvas.swapBuffers();
        canvas.repaint();
    }

    public void mouseEntered(MouseEvent e) {
       //System.out.println("Mouse entered " + e);
    }

    public void mouseExited(MouseEvent e) {
       //System.out.println("Mouse exited " +  e);
    }

    public void mouseClicked(MouseEvent e) {
       //System.out.println("Mouse clicked (# of clicks: " + e.getClickCount() + ") " + e);
    }

    public void mouseWheelMoved(MouseWheelEvent e) {
        System.out.println(e.getWheelRotation());
    }

    private void addToolBarButtons() {

        HashMap<Camera.VIEW, JButton> viewButtons = new HashMap<Camera.VIEW, JButton>();

        for(Camera.VIEW view : Camera.VIEW.values()) {
            JButton button = new JButton(view.toString());
            button.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  viewport.getCamera().setView(Camera.VIEW.valueOf(e.getActionCommand()));
                  canvas.repaint();
              }
            });
            viewButtons.put(view, button);
            toolBar.add(button);
        }

        toolBar.addSeparator();

        //
        // Create the camera manipulator buttons based on the ones in the Camera object
        //

        ActionListener manipButtonListener = new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  viewport.getCamera().setActiveManipulator(e.getActionCommand());
                  canvas.repaint();
              }
        };

        HashMap<String, JToggleButton> manipButtons = new HashMap<String, JToggleButton>();

        for(Map.Entry entry : viewport.getCamera().getManipulatorEntrySet()) {
            JToggleButton button = new JToggleButton((String) entry.getKey());
            button.addActionListener(manipButtonListener);
            button.setSelected(((Manipulable.NamedManipulator)entry.getValue()).isActive());
            manipButtons.put((String) entry.getKey(), button);
        }

        ButtonGroup manipGroup = new ButtonGroup();

        for(Map.Entry<String, JToggleButton> manip : manipButtons.entrySet()) {
            manipGroup.add(manip.getValue());
            toolBar.add(manip.getValue());
        }

        toolBar.addSeparator();

        //
        // Create the combo box that lists the available projections
        //

        ActionListener projComboListener = new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  JComboBox cb = (JComboBox) e.getSource();
                  viewport.getCamera().setProjection(Camera.PROJECTION.valueOf((String) cb.getSelectedItem()));
                  canvas.repaint();
              }
        };

        Vector<String> projs = new Vector<String>();
        
        for(Camera.PROJECTION proj : Camera.PROJECTION.values()) {
            projs.add(proj.toString());
        }

        JComboBox projCombo = new JComboBox(projs);
        projCombo.setSelectedIndex(viewport.getCamera().getProjection().ordinal());
        projCombo.addActionListener(projComboListener);

        toolBar.add(projCombo);
    }
}
